home *** CD-ROM | disk | FTP | other *** search
/ Freelog 9 / Freelog009.iso / BAS / Internet / Rtf2Html / Source C / RTFPARSE / RTFPARSE.C < prev    next >
C/C++ Source or Header  |  1999-06-27  |  38KB  |  1,281 lines

  1.  
  2. /*           
  3.  * %%File: rtfparse.c
  4.  *
  5.  * Copyright (c) 1995-1999 Bertrand LE QUELLEC
  6.  * Copyright (c) 1989-1995 Microsoft Corporation.
  7.  *
  8.  *
  9.  * http://perso.wanadoo.fr/blq
  10.  * blq@wanadoo.fr
  11.  */
  12.  
  13. #include <stdio.h>
  14. #include <stddef.h>
  15.  
  16.  
  17. #include "html.h"
  18. #include "rtftype.h"
  19. #include "rtfdecl.h"
  20. #include "rtfreadr.h"
  21. #include "mparse.h"
  22. #include "rtfhtml.h"
  23.  
  24. #define SOURCE_ACTN 1
  25. #include "rtfparse.h"
  26.                 
  27.               
  28.  
  29.               
  30. /*
  31.  * RTF parser tables
  32.  * Property descriptions
  33.  */
  34. PROP rgprop [ipropMax] = {
  35.     actnByte,   propChp,    offsetof(CHP, fBold),       /* ipropBold */
  36.     actnByte,   propChp,    offsetof(CHP, fItalic),     /* ipropItalic */
  37.     actnByte,   propChp,    offsetof(CHP, fUnderline),  /* ipropUnderline */
  38.     actnWord,   propPap,    offsetof(PAP, xaLeft),      /* ipropLeftInd */
  39.     actnWord,   propPap,    offsetof(PAP, xaRight),     /* ipropRightInd */
  40.     actnWord,   propPap,    offsetof(PAP, xaFirst),     /* ipropFirstInd */
  41.     actnWord,   propSep,    offsetof(SEP, cCols),       /* ipropCols */
  42.     actnWord,   propSep,    offsetof(SEP, xaPgn),       /* ipropPgnX */
  43.     actnWord,   propSep,    offsetof(SEP, yaPgn),       /* ipropPgnY */
  44.     actnWord,   propDop,    offsetof(DOP, xaPage),      /* ipropXaPage */
  45.     actnWord,   propDop,    offsetof(DOP, yaPage),      /* ipropYaPage */
  46.     actnWord,   propDop,    offsetof(DOP, xaLeft),      /* ipropXaLeft */
  47.     actnWord,   propDop,    offsetof(DOP, xaRight),     /* ipropXaRight */
  48.     actnWord,   propDop,    offsetof(DOP, yaTop),       /* ipropYaTop */
  49.     actnWord,   propDop,    offsetof(DOP, yaBottom),    /* ipropYaBottom */
  50.     actnWord,   propDop,    offsetof(DOP, pgnStart),    /* ipropPgnStart */
  51.     actnByte,   propSep,    offsetof(SEP, sbk),         /* ipropSbk */
  52.     actnByte,   propSep,    offsetof(SEP, pgnFormat),   /* ipropPgnFormat */
  53.     actnByte,   propDop,    offsetof(DOP, fFacingp),    /* ipropFacingp */
  54.     actnByte,   propDop,    offsetof(DOP, fLandscape),  /* ipropLandscape */
  55.     actnByte,   propPap,    offsetof(PAP, just),        /* ipropJust */
  56.     actnSpec,   propPap,    0,                          /* ipropPard */
  57.     actnSpec,   propChp,    0,                          /* ipropPlain */
  58.     actnSpec,   propSep,    0,                          /* ipropSectd */
  59. };
  60.  
  61.  
  62. /* Keyword descriptions */
  63. SYM rgsymRtf[] = {
  64. /*  keyword     dflt    fPassDflt   kwd         idx */
  65.     "b",        1,      fFalse,     kwdProp,    ipropBold,
  66.     "u",        1,      fFalse,     kwdProp,    ipropUnderline,
  67.     "i",        1,      fFalse,     kwdProp,    ipropItalic,
  68.     "ri",       0,      fFalse,     kwdProp,    ipropRightInd,
  69.     "fi",       0,      fFalse,     kwdProp,    ipropFirstInd,
  70.     "li",       0,      fFalse,     kwdProp,    ipropLeftInd,
  71.     "cols",     1,      fFalse,     kwdProp,    ipropCols,
  72.     "sbknone",  sbkNon, fTrue,      kwdProp,    ipropSbk,
  73.     "sbkcol",   sbkCol, fTrue,      kwdProp,    ipropSbk,
  74.     "sbkeven",  sbkEvn, fTrue,      kwdProp,    ipropSbk,
  75.     "sbkodd",   sbkOdd, fTrue,      kwdProp,    ipropSbk,
  76.     "sbkpage",  sbkPg,  fTrue,      kwdProp,    ipropSbk,
  77.     "pgnx",     0,      fFalse,     kwdProp,    ipropPgnX,
  78.     "pgny",     0,      fFalse,     kwdProp,    ipropPgnY,
  79.     "pgndec",   pgDec,  fTrue,      kwdProp,    ipropPgnFormat,
  80.     "pgnucrm",  pgURom, fTrue,      kwdProp,    ipropPgnFormat,
  81.     "pgnlcrm",  pgLRom, fTrue,      kwdProp,    ipropPgnFormat,
  82.     "pgnucltr", pgULtr, fTrue,      kwdProp,    ipropPgnFormat,
  83.     "pgnlcltr", pgLLtr, fTrue,      kwdProp,    ipropPgnFormat,
  84.     "qc",       justC,  fTrue,      kwdProp,    ipropJust,
  85.     "ql",       justL,  fTrue,      kwdProp,    ipropJust,
  86.     "qr",       justR,  fTrue,      kwdProp,    ipropJust,
  87.     "qj",       justF,  fTrue,      kwdProp,    ipropJust,
  88.     "paperw",   12240,  fFalse,     kwdProp,    ipropXaPage,
  89.     "paperh",   15480,  fFalse,     kwdProp,    ipropYaPage,
  90.     "margl",    1800,   fFalse,     kwdProp,    ipropXaLeft,
  91.     "margr",    1800,   fFalse,     kwdProp,    ipropXaRight,
  92.     "margt",    1440,   fFalse,     kwdProp,    ipropYaTop,
  93.     "margb",    1440,   fFalse,     kwdProp,    ipropYaBottom,
  94.     "pgnstart", 1,      fTrue,      kwdProp,    ipropPgnStart,
  95.     "facingp",  1,      fTrue,      kwdProp,    ipropFacingp,
  96.     "landscape",1,      fTrue,      kwdProp,    ipropLandscape,
  97.     "pict",     0,      fFalse,     kwdProp,    ipropImg,
  98.     "object",   0,      fFalse,     kwdProp,    ipropImg,
  99.     "pntext",   0,      fTrue,      kwdProp,    ipropPnText,
  100.     "par",      0,      fTrue,      kwdProp,    ipropPar,
  101.     "pard",     0,      fTrue,      kwdProp,    ipropPard,
  102.     "plain",    0,      fTrue,      kwdProp,    ipropPlain,
  103.     "field",    0,      fTrue,      kwdProp,    ipropField,
  104.     "bullet",   0,      fTrue,      kwdProp,    ipropBullet,
  105.     "sect",     0,      fTrue,      kwdProp,    ipropSectd,
  106.     "page",     0,      fTrue,      kwdProp,    ipropPage,
  107.     "sb",         0,      fTrue,      kwdProp,    ipropSB,
  108.     "chftn",    0,      fTrue,      kwdProp,    ipropChftn,
  109.     "footnote", 0,      fTrue,      kwdProp,    ipropFoot,
  110.     "fldrslt",  0,      fTrue,      kwdProp,    ipropFldrslt,
  111.     "\0x0a",    0,      fFalse,     kwdChar,    0x0a,
  112.     "\0x0d",    0,      fFalse,     kwdChar,    0x0a,
  113.     "tab",      0,      fFalse,     kwdChar,    0x09,
  114.     "emdash",   0,      fFalse,     kwdChar,    '-',
  115.     "endash",   0,      fFalse,     kwdChar,    '-',
  116.     "ldblquote",0,      fFalse,     kwdChar,    '"',
  117.     "rdblquote",0,      fFalse,     kwdChar,    '"',
  118.     "lquote",   0,      fFalse,     kwdChar,    '`',
  119.     "rquote",   0,      fFalse,     kwdChar,    '\'',
  120.     "line",     0,      fFalse,     kwdChar,    ' ',
  121.     "bin",      0,      fFalse,     kwdSpec,    ipfnBin,
  122.     "*",        0,      fFalse,     kwdSpec,    ipfnSkipDest,
  123.     "bkmkstart",0,      fFalse,     kwdBkmk,    idestSkip,
  124.     "trowd",    0,      fFalse,     kwdTableau, idestSkip,
  125.     "intbl",    0,      fFalse,     kwdIntbl,   idestSkip,
  126.     "cellx",    0,      fFalse,     kwdCellx,   idestSkip,
  127.     "cell",     0,      fFalse,     kwdCell,    idestSkip,
  128.     "row",      0,      fFalse,     kwdFinTableau,  idestSkip,
  129.     "f",        0,      fFalse,     kwdFont,    idestSkip,
  130.     "header",   0,      fFalse,     kwdHeader,  idestSkip,
  131.     "s",        0,      fFalse,     kwdNiveau,  idestSkip,
  132.     "'a",       0,      fFalse,     kwdAccent,  idestSkip,
  133.     "'b",       0,      fFalse,     kwdAccent,  idestSkip,
  134.     "'c",       0,      fFalse,     kwdAccent,  idestSkip,
  135.     "'d",       0,      fFalse,     kwdAccent,  idestSkip,
  136.     "'e",       0,      fFalse,     kwdAccent,  idestSkip,
  137.     "'f",       0,      fFalse,     kwdAccent,  idestSkip,
  138.     "'0",       0,      fFalse,     kwdAccent,  idestSkip,
  139.     "'1",       0,      fFalse,     kwdAccent,  idestSkip,
  140.     "'2",       0,      fFalse,     kwdAccent,  idestSkip,
  141.     "'3",       0,      fFalse,     kwdAccent,  idestSkip,
  142.     "'4",       0,      fFalse,     kwdAccent,  idestSkip,
  143.     "'5",       0,      fFalse,     kwdAccent,  idestSkip,
  144.     "'7",       0,      fFalse,     kwdAccent,  idestSkip,
  145.     "'6",       0,      fFalse,     kwdAccent,  idestSkip,
  146.     "'7",       0,      fFalse,     kwdAccent,  idestSkip,
  147.     "'8",       0,      fFalse,     kwdAccent,  idestSkip,
  148.     "'9",       0,      fFalse,     kwdAccent,  idestSkip,
  149.     "author",   0,      fFalse,     kwdDest,    idestSkip,
  150.     "buptim",   0,      fFalse,     kwdDest,    idestSkip,
  151.     "colortbl", 0,      fFalse,     kwdDest,    idestSkip,
  152.     "comment",  0,      fFalse,     kwdDest,    idestSkip,
  153.     "creatim",  0,      fFalse,     kwdDest,    idestSkip,
  154.     "doccomm",  0,      fFalse,     kwdDest,    idestSkip,
  155.     "fonttbl",  0,      fFalse,     kwdDest,    idestSkip,
  156.     "footer",   0,      fFalse,     kwdDest,    idestSkip,
  157.     "footerf",  0,      fFalse,     kwdDest,    idestSkip,
  158.     "footerl",  0,      fFalse,     kwdDest,    idestSkip,
  159.     "footerr",  0,      fFalse,     kwdDest,    idestSkip,
  160.     "fldinst",  0,      fFalse,     kwdDest,    idestSkip,
  161.     "ftncn",    0,      fFalse,     kwdDest,    idestSkip,
  162.     "ftnsep",   0,      fFalse,     kwdDest,    idestSkip,
  163.     "ftnsepc",  0,      fFalse,     kwdDest,    idestSkip,
  164.     "headerf",  0,      fFalse,     kwdDest,    idestSkip,
  165.     "headerl",  0,      fFalse,     kwdDest,    idestSkip,
  166.     "headerr",  0,      fFalse,     kwdDest,    idestSkip,
  167.     "info",     0,      fFalse,     kwdDest,    idestSkip,
  168.     "keywords", 0,      fFalse,     kwdDest,    idestSkip,
  169.     "operator", 0,      fFalse,     kwdDest,    idestSkip,
  170.     "printim",  0,      fFalse,     kwdDest,    idestSkip,
  171.     "private1", 0,      fFalse,     kwdDest,    idestSkip,
  172.     "revtim",   0,      fFalse,     kwdDest,    idestSkip,
  173.     "rxe",      0,      fFalse,     kwdDest,    idestSkip,
  174.     "stylesheet",   0,  fFalse,     kwdDest,    idestSkip,
  175.     "subject",  0,      fFalse,     kwdDest,    idestSkip,
  176.     "tc",       0,      fFalse,     kwdDest,    idestSkip,
  177.     "title",    0,      fFalse,     kwdDest,    idestSkip,
  178.     "txe",      0,      fFalse,     kwdDest,    idestSkip,
  179.     "xe",       0,      fFalse,     kwdDest,    idestSkip,
  180.     "{",        0,      fFalse,     kwdChar,    '{',
  181.     "}",        0,      fFalse,     kwdChar,    '}',
  182.     "\\",       0,      fFalse,     kwdChar,    '\\',
  183.     "mac",      0,      fFalse,     kwdMac,     idestSkip,
  184.     "ansi",     0,      fFalse,     kwdAnsi,    idestSkip
  185.     };
  186.  
  187.  
  188. int isymMax = sizeof(rgsymRtf) / sizeof(SYM);
  189.  
  190.  
  191. /* ------------------------------------------------------------------------- */
  192.  
  193.  
  194. /*
  195.  * %%Function: ecChangeDest
  196.  *
  197.  * Change to the destination specified by idest.
  198.  * There's usually more to do here than this...
  199.  */
  200. static int ecChangeDest(IDEST idest)
  201. {
  202.     if (rds == rdsSkip)             /* if we're skipping text, */
  203.         return ecOK;                /* don't do anything */
  204.  
  205.     switch (idest)
  206.     {
  207.         default:
  208.             rds = rdsSkip;      /* when in doubt, skip it... */
  209.             break;
  210.     }
  211.  
  212.     return ecOK;
  213. }
  214.  
  215. /* 
  216.  * %%Function: ecParseSpecialProperty
  217.  *
  218.  * Set a property that requires code to evaluate.
  219.  */
  220. static int ecParseSpecialProperty(IPROP iprop, int isym)
  221. {
  222.     char tmp[MLEN];
  223.     register int ct;
  224.     
  225.  
  226.     switch (iprop)
  227.     {
  228.         case ipropChftn:
  229.             carniv = 0;
  230.             break;
  231.                 
  232.         /* Detection et prise en compte d'une image */
  233.         case ipropImg:
  234.             sprintf(tmp, "%s%d.gif", prefigure, ++nbFigure);
  235.             sprintf(tmp, "%s", GetImgSrcHTML(tmp));
  236.             
  237.             TestLibPrintString(tmp, fpOut);
  238.  
  239.             return ecChangeDest(rgsymRtf[isym].idx);
  240.  
  241.         case ipropFldrslt:
  242.             nbResult = 0;
  243.             flagFldrslt = 1;
  244.             break;
  245.                    
  246.         /* DΘtection et prise en compte d'une note de bas de page */           
  247.         case ipropFoot:
  248.             valCrochetF = crochet;
  249.  
  250.             if(oldProp == ipropChftn && !carniv)
  251.             {
  252.                 carniv = 0;
  253.                 flagFootnote = 1;
  254.                 nbFootnote += 1;
  255.  
  256.                 sprintf(tmp, "%d", nbFootnote);
  257.                 
  258.                 if (flagFRAME)
  259.                     sprintf(tmp, "%s%s%s",
  260.                         TAG_B, GetAHNameTargetHTML(noteFile, NOTE_FRAME, tmp), TAGf_B);    
  261.                 else
  262.                     sprintf(tmp, "%s%s%s", TAG_B, GetAHNameHTML(tmp), TAGf_B);
  263.                         
  264.                 TestLibPrintString(tmp, fpOut);
  265.  
  266.                 Notes[carnot] = '\0';
  267.  
  268.                 if(strlen(Notes))
  269.                 {                     
  270.                     if(nbnote < MLEN / 2)
  271.                         sprintf(lesNotes[nbnote++], "%s", Notes);
  272.                 }
  273.                 
  274.                 carnot = 0;
  275.                 Notes[carnot] = '\0';
  276.                 lesNotes[nbnote][0] = '\0';
  277.             }
  278.  
  279.             break;
  280.  
  281.         case ipropPar:
  282.             flagStop = 1;
  283.             
  284.             if(!niveau)
  285.             {
  286.                 if(flagTOC)
  287.                 {
  288.                     lesCar[nbcar] = '\0';
  289.  
  290.                     libPrintString(GetAHNameHTML(libRTrim(lesCar)), fpOut);
  291.                     libPrintCharStd('\n', fpOut);
  292.                 }
  293.             }
  294.             
  295.             if(fontSize)
  296.             {
  297.                 fontSize = 0;
  298.                  
  299.                 libPrintString(TAGf_FONT, fpOut);
  300.             }
  301.                    
  302.             if (strlen(Url) > 4)
  303.             {
  304.                 libPrintString(GetHrefHTML2(Url, Url),fpOut);
  305.                 
  306.                 flagStop = 0;
  307.                 nbUrl = 0;
  308.                 Url[nbUrl] = '\0';
  309.             }
  310.             
  311.              if (!flagTableau)
  312.              {
  313.                 if(flagBR_P == 1)
  314.                 {
  315.                     if(tagDD)
  316.                         sprintf(tmp, "%s\n", TAG_BR);
  317.                     else
  318.                         sprintf(tmp, "%s\n", TAG_P);
  319.                 }
  320.                 else if(flagBR_P == 0)
  321.                    sprintf(tmp, "%s\n", TAG_BR);
  322.             }
  323.             else if (flagTableau)
  324.                 sprintf(tmp, "%s\n", TAG_BR);
  325.  
  326.             TestLibPrintString(tmp, fpOut);
  327.             
  328.             nbcar = 0;
  329.             flagDD = 0;
  330.             break;
  331.  
  332.         case ipropPnText:
  333.             nbcar = 0;
  334.             flagPnText = 1;
  335.             break;
  336.  
  337.         case ipropPard:
  338.             memset(&pap, 0, sizeof(pap));
  339.             ecDetectPard();
  340.             break;
  341.     
  342.         case ipropPlain:
  343.             memset(&chp, 0, sizeof(chp));
  344.             break;
  345.         
  346.         case ipropSB:
  347.             if (!flagFootnote)
  348.             {
  349.                 TestLibPrintString(TAG_P, fpOut);
  350.                 libPrintCharStd('\n', fpOut);
  351.             }
  352.                 
  353.             break;
  354.                       
  355.         /* Detection saut de page ou changement de section */          
  356.         case ipropPage:
  357.         case ipropSectd:
  358.             memset(&sep, 0, sizeof(sep));
  359.  
  360.             /* Affichage de fin de style eventuel */
  361.             ecPrintItalicF    (fpOut);
  362.             ecPrintBoldF    (fpOut);
  363.             
  364.             if(tagUL)
  365.             {
  366.                 tagUL = 0;
  367.                  
  368.                 libPrintString(TAGf_UL, fpOut);
  369.                 libPrintCharStd('\n', fpOut);
  370.  
  371.                 while(flagTOC)
  372.                 {
  373.                     flagTOC -= 1;
  374.                     
  375.                     libPrintCharStd('\n', fpOut);
  376.                     libPrintString(TAGf_UL, fpOut);
  377.                     libPrintCharStd('\n', fpOut);
  378.                 }
  379.             }
  380.  
  381.             flagTOC = 0;
  382.  
  383.             if(tagCenter)
  384.             {
  385.                 tagCenter = 0;
  386.                 
  387.                 libPrintCharStd('\n', fpOut);
  388.                 libPrintString(TAGf_CENTER, fpOut);
  389.                 libPrintCharStd('\n', fpOut);
  390.             }
  391.  
  392.             if(niveau)
  393.             {
  394.                 leNiveau [carniv] = '\0';
  395.  
  396.                 if(strlen(libRTrim(leNiveau)))
  397.                 { 
  398.                     libPrintString(GetNiveauHTML(niveau + plusNiveau), fpOut);
  399.                     libPrintString(GetANameHTML(leNiveau), fpOut);
  400.                     libPrintString(GetNiveauHTMLf(niveau + plusNiveau), fpOut);
  401.                     
  402.                     if (flagFRAME)
  403.                     {      
  404.                         if (niveau == oldNiveau)
  405.                         {
  406.                             libPrintCharStd('\n', fpTable);
  407.                             libPrintString(TAG_LI, fpTable);
  408.                             libPrintString(GetAHNameTargetHTML(pageFile, PAGE_FRAME, leNiveau), fpTable);
  409.                         }
  410.                         else
  411.                         {
  412.                             if (niveau < oldNiveau)
  413.                             {    
  414.                                 for (ct = niveau; ct <= oldNiveau; ct++)
  415.                                     libPrintString(TAGf_UL, fpTable);
  416.                             }
  417.                             else if (niveau > oldNiveau && oldNiveau > 0)
  418.                                 libPrintString(TAG_UL, fpTable);
  419.                                                          
  420.                             libPrintCharStd('\n', fpTable);                            
  421.                             libPrintString(TAG_LI, fpTable);
  422.                             libPrintString(GetAHNameTargetHTML(pageFile, PAGE_FRAME, leNiveau), fpTable);
  423.                         }
  424.                         
  425.                         libPrintCharStd('\n', fpTable);
  426.                     }
  427.                     
  428.                     oldNiveau = niveau; 
  429.                 }
  430.             }
  431.  
  432.             if(flagFootnote == -1)
  433.                 ecFootnote();
  434.  
  435.             if(flagBR_P == 1)
  436.             {
  437.                 if(tagDD)
  438.                 {
  439.                     libPrintString(TAG_BR, fpOut);
  440.                 }
  441.                 else
  442.                     libPrintString(TAG_P, fpOut);
  443.             }
  444.             else
  445.             {
  446.                 libPrintString(TAG_BR, fpOut);
  447.             }
  448.  
  449.             libPrintString(TAG_HR4, fpOut);
  450.             libPrintString(TAG_BR, fpOut);
  451.             libPrintCharStd('\n', fpOut);
  452.  
  453.             tagLI = 0;
  454.             nbcar = 0;
  455.             niveau = 0;     
  456.             flagDD = 0;
  457.             flagTOC = 0;    
  458.             flagFootnote = 0;
  459.             //detectField = 0;
  460.  
  461.             break;
  462.     
  463.         case ipropField:
  464.             //detectField = 1;
  465.             break;
  466.  
  467.         case ipropFldinst:
  468.             break;
  469.  
  470.         case ipropBullet: 
  471.             sprintf(tmp, "\n%s", TAG_LI);
  472.             TestLibPrintString(tmp, fpOut);
  473.             
  474.             break;
  475.  
  476.         case ipropItalic:
  477.             if(!flagTOC && !niveau)
  478.                 ecPrintItalic(fpOut);
  479.  
  480.             break;
  481.  
  482.         case ipropBold:
  483.             if(!flagTOC && !niveau)
  484.                 ecPrintBold(fpOut);
  485.                     
  486.             break;
  487.  
  488.         case ipropUnderline:
  489.             break;
  490.  
  491.         default:
  492.             return ecBadTable;
  493.     }
  494.  
  495.     oldProp = iprop;
  496.     return ecOK;
  497. }
  498.  
  499.  
  500. /*
  501.  * %%Function: ecApplyPropChange
  502.  *
  503.  * Set the property identified by _iprop_ to the value _val_.
  504.  */
  505. static int ecApplyPropChange(IPROP iprop, int val, int isym)
  506. {
  507.     char * pb = (char *)0;
  508.            
  509.            
  510.     if (rds == rdsSkip)                 /* If we're skipping text, */
  511.         return ecOK;                    /* don't do anything. */
  512.  
  513.     switch (rgprop[iprop].prop)
  514.     {
  515.         case propDop:
  516.             pb = (char *)&dop;
  517.             break;    
  518.             
  519.         case propSep:
  520.             pb = (char *)&sep;
  521.             break;        
  522.             
  523.         case propPap:
  524.             pb = (char *)&pap;
  525.             break;    
  526.             
  527.         case propChp:
  528.             pb = (char *)&chp;
  529.             break;     
  530.             
  531.         default:
  532.             if (rgprop[iprop].actn != actnSpec)
  533.                 return ecBadTable;  
  534.                 
  535.             break;
  536.     }
  537.  
  538.     switch (rgprop[iprop].actn)
  539.     {
  540.         case actnByte:
  541.             pb[rgprop[iprop].offset] = (unsigned char) val;
  542.  
  543.             if (rgprop[iprop].prop == propChp)
  544.                 return ecParseSpecialProperty(iprop, isym);
  545.  
  546.             if(val == justC)
  547.                 ecPrintCenter(fpOut);
  548.             
  549.             break;
  550.     
  551.         case actnWord:
  552.             if(rgprop[iprop].offset == offsetof(PAP, xaLeft))
  553.             {
  554.                 tagDD = 1;
  555.                 flagDD = 1;                    
  556.                 libPrintString(TAG_DD, fpOut);
  557.             }
  558.             else
  559.             {
  560.                 (*(int *) (pb+rgprop[iprop].offset)) = val;
  561.             }
  562.             
  563.             break;
  564.     
  565.         case actnSpec:
  566.             return ecParseSpecialProperty(iprop, isym);
  567.     
  568.         default:
  569.             return ecBadTable;
  570.     }
  571.  
  572.     return ecOK;
  573. }
  574.  
  575.  
  576.  
  577. /* 
  578.  * %%Function: ecParseSpecialKeyword
  579.  *
  580.  * Evaluate an RTF control that needs special processing.
  581.  */
  582. static int ecParseSpecialKeyword(IPFN ipfn)
  583. {
  584.     /* if we're skipping, and it's not */
  585.     if (rds == rdsSkip && ipfn != ipfnBin)
  586.         return ecOK;    /* the \bin keyword, ignore it. */
  587.     
  588.     switch (ipfn)
  589.     {
  590.         case ipfnBin:
  591.             ris = risBin;
  592.             cbBin = lParam;
  593.             break;
  594.             
  595.         case ipfnSkipDest:
  596.             fSkipDestIfUnk = fTrue;
  597.             break;
  598.             
  599.         case ipfnHex:
  600.             ris = risHex;
  601.             break;
  602.  
  603.         default:
  604.             return ecBadTable;
  605.     }
  606.  
  607.     return ecOK;
  608. }
  609.  
  610.  
  611. /* 
  612.  * %%Function: ecTranslateKeyword.
  613.  * 
  614.  * Step 3. 
  615.  * Search rgsymRtf for szKeyword and evaluate it appropriately. 
  616.  * 
  617.  * Inputs: 
  618.  * szKeyword:   The RTF control to evaluate. 
  619.  * param:       The parameter of the RTF control.
  620.  * fParam:      fTrue if the control had a parameter; (i.e., if param is valid) 
  621.  *              fFalse if it did not. 
  622.  */
  623. int ecTranslateKeyword(char * szKeyword, int param, bool fParam)
  624. {
  625.     int     isym = 0, ct;
  626.     char *  tag = (char *)0;
  627.  
  628.  
  629.     /* search for szKeyword in rgsymRtf */
  630.     for (isym = 0; isym < isymMax; isym++)
  631.     {
  632.         if (strcmp(szKeyword, rgsymRtf[isym].szKeyword) == 0)
  633.             break;
  634.     }
  635.  
  636.     if (isym == isymMax)        /* control word not found */
  637.     {
  638.         if (fSkipDestIfUnk) /* if this is a new destination */
  639.             rds = rdsSkip;  /* skip the destination */
  640.         
  641.         /* else just discard it */
  642.         fSkipDestIfUnk = fFalse;
  643.         
  644.         return ecOK;
  645.     }
  646.  
  647.     /* found it!  use kwd and idx to determine what to do with it. */
  648.     fSkipDestIfUnk = fFalse;
  649.  
  650.     switch (rgsymRtf[isym].kwd)
  651.     {
  652.         case kwdProp:
  653.             if (rgsymRtf[isym].fPassDflt || !fParam)
  654.                 param = rgsymRtf[isym].dflt; 
  655.                     
  656.             return ecApplyPropChange(rgsymRtf[isym].idx, param, isym);
  657.  
  658.         case kwdChar:
  659.             return ecParseChar(rgsymRtf[isym].idx);
  660.  
  661.         case kwdDest:
  662.             return ecChangeDest(rgsymRtf[isym].idx);
  663.  
  664.         case kwdSpec:
  665.             return ecParseSpecialKeyword(rgsymRtf[isym].idx);
  666.                  
  667.          /* Bookmark */
  668.         case kwdBkmk:
  669.             flagBKMK = 1;
  670.             nbBk = 0;
  671.             lesBkmk[nbBk] = '\0';
  672.             
  673.             break;
  674.               
  675.         case kwdIntbl:
  676.             /* Le format tableau RTF doit correpondre de maniere
  677.              * "generale" a :
  678.              * \trowd ... \cellx... \pard ... \intbl ... \cell ... \row
  679.              *
  680.              *  \trowd  : indique un debut de tableau
  681.              *  \cell   : indique une fin de cellule
  682.              *  \row    : indique une fin de tableau
  683.              *
  684.              * Si on detecte de \intbl sans etre dans un tableau cela
  685.              * signifie que le paragraphe en cours appartient au tableau
  686.              * precedent.
  687.              * Il est donc necessaire de revenir dans le fichier de sortie
  688.              * avant la fermture du tableau HTML (ouf!!...).
  689.             */ 
  690.             if(flagTableau == 0)
  691.             {
  692.                 
  693.                 fflush(fpOut);
  694.  
  695.                 if(tagCenter)
  696.                 {
  697.                     if(!(fseek(fpOut, ftell(fpOut) - (strlen(TAGf_TABLE) + strlen(TAG_CENTER)+10), SEEK_SET)))  
  698.                         flagTableau = 1;
  699.  
  700.                     tagCenter = 0;
  701.                 }
  702.                 else
  703.                 {
  704.                     if(!(fseek(fpOut, ftell(fpOut) - (strlen(TAGf_TABLE) +7), SEEK_SET)))
  705.                         flagTableau = 1;
  706.                 }
  707.                 
  708.                 tagUL = 0;
  709.  
  710.                 if(!tagTR)
  711.                 {
  712.                     tagTR = 1;
  713.  
  714.                     libPrintString(TAG_TR, fpOut);
  715.                     libPrintCharStd('\n', fpOut);
  716.                 }
  717.             }
  718.  
  719.             break;        
  720.  
  721.         /* Mode Tableau */
  722.         case kwdTableau:
  723.             if(flagTableau == 0)
  724.             {
  725.                 if(tagCenter)
  726.                 {
  727.                     tagCenter = 0;
  728.  
  729.                     libPrintCharStd('\n', fpOut);
  730.                     libPrintString(TAGf_CENTER, fpOut);
  731.                     libPrintCharStd('\n', fpOut);
  732.                 }
  733.                 
  734.                 libPrintString(GetTableHTML(), fpOut);
  735.             }
  736.  
  737.             if(!tagTR)
  738.             {
  739.                 tagTR = 1;
  740.  
  741.                 libPrintString(TAG_TR, fpOut);
  742.                 libPrintCharStd('\n', fpOut);
  743.             }
  744.  
  745.             flagTableau = 1;
  746.  
  747.             break;
  748.  
  749.         case kwdCellx:
  750.             nbcell +=1;
  751.             break;
  752.  
  753.         case kwdCell:
  754.             switch(flagTableau)
  755.             {
  756.                 case 0:
  757.                     flagTableau = 1;
  758.                         
  759.                     libPrintString(GetTableHTML(), fpOut);
  760.  
  761.                     if(!tagTR)
  762.                     {
  763.                         tagTR = 1;
  764.  
  765.                         libPrintString(TAG_TR, fpOut);
  766.                         libPrintCharStd('\n', fpOut);
  767.                     }
  768.  
  769.                     break;
  770.  
  771.                 case -1:
  772.                 case 1:
  773.                     break;
  774.             }
  775.  
  776.             if(!strlen(cellule))
  777.                 sprintf(cellule, "-");
  778.  
  779.             if(nbcell == 1)
  780.             {
  781.                 if(oldnbcell > nbcell)
  782.                 {
  783.                     CelluleColHTML(cellule, fpOut, oldnbcell + 1);
  784.                 }
  785.                 else
  786.                 {
  787.                     CelluleColHTML(cellule, fpOut, (nbcell ? nbcell : 1) + 1);
  788.                 }
  789.             }
  790.             else
  791.             {
  792.                 CelluleHTML(cellule, fpOut);
  793.             }
  794.             
  795.             if(tagCenter)
  796.             {
  797.                 tagCenter = 0;
  798.                 libPrintString(TAGf_CENTER, fpOut);
  799.                 libPrintCharStd('\n', fpOut);
  800.             }
  801.             
  802.             /* Affichage de fin de style eventuel */
  803.             ecPrintItalicF    (fpOut);
  804.             ecPrintBoldF    (fpOut);
  805.             
  806.             carcell = 0;
  807.             cellule[carcell] = '\0';
  808.             
  809.             break;          
  810.             
  811.         /* Fin de tableau */
  812.         case kwdFinTableau:
  813.             if(tagTR)
  814.             {
  815.                 libPrintString(TAGf_TR, fpOut);
  816.             }
  817.             
  818.             if(tagCenter)
  819.             {
  820.                 tagCenter = 0;
  821.                 libPrintString(TAGf_CENTER, fpOut);
  822.             }
  823.             
  824.             tagTR = 0;
  825.             oldnbcell = nbcell;
  826.             nbcell = 0;
  827.             flagTableau = -1;
  828.             break;
  829.  
  830.         case kwdHeader:
  831.             flagHeader = 1;
  832.             valCrochetH = crochet;
  833.             break;
  834.  
  835.         case kwdFont:
  836.             break;
  837.  
  838.         /* Detection des niveaux : */
  839.         case kwdNiveau:
  840.             /* Equivalence de designation des niveau US->Fr. */
  841.             switch(param)
  842.             {
  843.                 case 41:
  844.                     param = 1;
  845.                 case 42:
  846.                     param = 2;
  847.                 case 43:
  848.                     param = 3;
  849.                 case 44:
  850.                     param = 4;
  851.                 case 45:
  852.                     param = 5;
  853.                 case 46:
  854.                     param = 6;
  855.                 case 47:
  856.                     param = 6;
  857.                 case 48:
  858.                     param = 8;
  859.                 case 49:
  860.                     param = 9;
  861.             }
  862.  
  863.             if(niveau)
  864.             {
  865.                 leNiveau [carniv] = '\0';
  866.  
  867.                 if(strlen(libRTrim(leNiveau)))
  868.                 {
  869.                     libPrintString(GetNiveauHTML(niveau + plusNiveau), fpOut);
  870.                     libPrintString(GetANameHTML(leNiveau), fpOut);
  871.                     libPrintString(GetNiveauHTMLf(niveau + plusNiveau), fpOut);
  872.                     
  873.                     if (flagFRAME)
  874.                     {      
  875.                         if (niveau == oldNiveau)
  876.                         {        
  877.                             libPrintCharStd('\n', fpTable);
  878.                             libPrintString(TAG_LI, fpTable);
  879.                             libPrintString(GetAHNameTargetHTML(pageFile, PAGE_FRAME, leNiveau), fpTable);
  880.                         }
  881.                         else
  882.                         {
  883.                             if (niveau < oldNiveau)
  884.                             {    
  885.                                 for (ct = niveau; ct <= oldNiveau; ct++)
  886.                                     libPrintString(TAGf_UL, fpTable);
  887.                             }
  888.                             else if (niveau > oldNiveau && oldNiveau > 0)
  889.                                 libPrintString(TAG_UL, fpTable);
  890.                                 
  891.                             libPrintCharStd('\n', fpTable);
  892.                             libPrintString(TAG_LI, fpTable);
  893.                             libPrintString(GetAHNameTargetHTML(pageFile, PAGE_FRAME, leNiveau), fpTable);
  894.                         }
  895.                         
  896.                         libPrintCharStd('\n', fpTable);
  897.                     }
  898.                     
  899.                     oldNiveau = niveau; 
  900.                 }
  901.             }
  902.  
  903.             carniv = 0;
  904.             niveau = 0;
  905.             leNiveau [carniv] = '\0';
  906.             tag = GetNiveauHTML(param + plusNiveau);
  907.  
  908.             if(tagUL && tag)
  909.             {
  910.                 tagUL = 0;
  911.                 
  912.                 libPrintCharStd('\n', fpOut);
  913.                 libPrintString(TAGf_UL, fpOut);
  914.                 libPrintCharStd('\n', fpOut);
  915.             } 
  916.             
  917.             if(tag)
  918.             {
  919.                 niveau = param ? param : 1;
  920.                 lesCar[nbcar] = '\0';
  921.  
  922.                 if(flagPnText == 1 && strlen(lesCar))
  923.                 {
  924.                     sprintf(leNiveau, "%s", lesCar);
  925.                     carniv = nbcar;
  926.                 }
  927.             }
  928.  
  929.             flagPnText = 0;
  930.             nbcar = 0;
  931.             break;
  932.  
  933.         /* Detection des accents : */
  934.         case kwdAccent:
  935.             if(flagGO)
  936.             {
  937.                 return HexaToHtmlOrTxt(szKeyword, param, fParam);
  938.             }
  939.  
  940.             break;
  941.  
  942.         case kwdMac:
  943.             return ecMacFile;
  944.  
  945.         case kwdAnsi:
  946.             break;
  947.  
  948.         default:
  949.             return ecBadTable;
  950.     }
  951.  
  952.     return ecOK;
  953. }
  954.  
  955.  
  956. /* 
  957.  * %%Function: ecEndGroupAction
  958.  *
  959.  * The destination specified by rds is coming to a close.
  960.  * If there's any cleanup that needs to be done, do it now.
  961.  */
  962. int ecEndGroupAction(RDS rds)
  963. {
  964.     return ecOK;
  965. }
  966.  
  967.  
  968. /*
  969.  * %%Function: ecDetectPard
  970.  *
  971.  */
  972. void ecDetectPard(void)
  973. {                    
  974.     int ct;
  975.     
  976.     
  977.     if (oldProp != ipropFoot)
  978.     {
  979.         /* Affichage de fin de style eventuel */
  980.         ecPrintItalicF    (fpOut);
  981.         ecPrintBoldF    (fpOut);
  982.     }
  983.     
  984.     if(tagLI && !valCrochetF)
  985.     {
  986.         tagLI = 0;
  987.         
  988.         libPrintString(TAGf_BQUOTE, fpOut);
  989.         libPrintCharStd('\n', fpOut);
  990.     }
  991.     
  992.     if(flagTableau == -1)
  993.     {
  994.         tagUL = 1;
  995.  
  996.         if(tagTR)
  997.         {
  998.             libPrintString(TAGf_TR, fpOut);
  999.             libPrintCharStd('\n', fpOut);
  1000.         }
  1001.  
  1002.         libPrintString(TAGf_TABLE, fpOut);
  1003.         libPrintCharStd('\n', fpOut);
  1004.  
  1005.         flagTableau = 0;
  1006.         tagTR = 0;
  1007.     }
  1008.  
  1009.     if(niveau && !flagTOC)
  1010.     {
  1011.         leNiveau [carniv] = '\0';
  1012.  
  1013.         if(strlen(libRTrim(leNiveau)))
  1014.         {
  1015.             libPrintString(GetNiveauHTML(niveau + plusNiveau), fpOut);
  1016.             libPrintCharStd('\n', fpOut);
  1017.             libPrintString(GetANameHTML(leNiveau), fpOut);
  1018.             libPrintString(GetNiveauHTMLf(niveau + plusNiveau), fpOut);
  1019.             libPrintCharStd('\n', fpOut);
  1020.              
  1021.             if (flagFRAME)
  1022.             {      
  1023.                 if (niveau == oldNiveau)
  1024.                 {                      
  1025.                     libPrintCharStd('\n', fpTable);
  1026.                     libPrintString(TAG_LI, fpTable);
  1027.                     libPrintString(GetAHNameTargetHTML(pageFile, PAGE_FRAME, leNiveau), fpTable);
  1028.                 }
  1029.                 else
  1030.                 {
  1031.                     if (niveau < oldNiveau)
  1032.                     {    
  1033.                         for (ct = niveau; ct <= oldNiveau; ct++)
  1034.                             libPrintString(TAGf_UL, fpTable);
  1035.                     }
  1036.                     else if (niveau > oldNiveau && oldNiveau > 0)
  1037.                         libPrintString(TAG_UL, fpTable);
  1038.                                
  1039.                     libPrintCharStd('\n', fpTable);
  1040.                     libPrintString(TAG_LI, fpTable);        
  1041.                     libPrintString(GetAHNameTargetHTML(pageFile, PAGE_FRAME, leNiveau), fpTable);
  1042.                 }
  1043.                 
  1044.                 libPrintCharStd('\n', fpTable);
  1045.             }
  1046.                     
  1047.             oldNiveau = niveau;
  1048.         }
  1049.  
  1050.         tagUL = 1;
  1051.         niveau = 0;
  1052.         carniv = 0;
  1053.         leNiveau [carniv] = '\0';
  1054.                     
  1055.         libPrintCharStd('\n', fpOut);
  1056.         libPrintString(TAG_UL, fpOut);
  1057.         libPrintCharStd('\n', fpOut);
  1058.     }
  1059.  
  1060.     if(tagCenter)
  1061.     {            
  1062.         if(oldProp != ipropFoot)
  1063.         {
  1064.             libPrintCharStd('\n', fpOut);
  1065.             tagCenter = 0;
  1066.     
  1067.             if(!flagTableau)
  1068.             {
  1069.                 libPrintString(TAGf_CENTER, fpOut);
  1070.                 libPrintCharStd('\n', fpOut);
  1071.             }
  1072.         }
  1073.     }
  1074.         
  1075.     if(fontSize)
  1076.     {
  1077.         fontSize = 0;
  1078.  
  1079.         libPrintString(TAGf_FONT, fpOut);
  1080.     }
  1081.     
  1082.     if(!flagPnText)
  1083.         nbcar = 0;
  1084.  
  1085.     oldnbcell = 0;
  1086.     flagGO = 1;
  1087.     //detectField = 0;
  1088.     oldProp = ipropPard;
  1089. }
  1090.  
  1091. /* 
  1092.  * %%Function: ecFootnote.
  1093.  *
  1094.  * Affiche la liste des notes de bas de page decouvert. 
  1095.  */
  1096. void ecFootnote(void)
  1097. {
  1098.     char tmp[5];
  1099.     int i = 0;
  1100.  
  1101.  
  1102.     Notes[carnot] = '\0';
  1103.  
  1104.     if(strlen(Notes))
  1105.     {       
  1106.         if(nbnote < MLEN / 2)
  1107.         {
  1108.             sprintf(lesNotes[nbnote++], "%s", Notes);
  1109.             lesNotes[nbnote][0] = '\0';
  1110.         }
  1111.     }
  1112.  
  1113.     for (i = 0; i < nbnote; i++)
  1114.     {
  1115.         if(!lesNotes[i])
  1116.             continue;
  1117.            
  1118.         flagNote = 1;
  1119.         
  1120.         if(flagBR_P)
  1121.         {
  1122.             if (flagFRAME)
  1123.                libPrintString(TAG_P, fpNote);
  1124.             else
  1125.                 libPrintString(TAG_P, fpOut);
  1126.         }
  1127.         else
  1128.         {
  1129.             if (flagFRAME)
  1130.                 libPrintString(TAG_BR, fpNote);
  1131.             else
  1132.                 libPrintString(TAG_BR, fpOut);
  1133.         }
  1134.  
  1135.         if (flagFRAME)
  1136.             libPrintCharStd('\n', fpNote);
  1137.         else
  1138.             libPrintCharStd('\n', fpOut);
  1139.         
  1140.         sprintf(tmp, "%d", (nbFootnote - (nbnote-1)) + i);
  1141.         
  1142.         if (flagFRAME)
  1143.         { 
  1144.             libPrintString("<B><EM>", fpNote);
  1145.             libPrintString(GetANameHTML(tmp), fpNote);
  1146.             libPrintString("</EM></B>", fpNote);
  1147.         }
  1148.         else
  1149.         {
  1150.             libPrintString("<B><EM>", fpOut);
  1151.             libPrintString(GetANameHTML(tmp), fpOut);
  1152.             libPrintString("</EM></B>", fpOut);
  1153.         }
  1154.         
  1155.         if(lesNotes[i])
  1156.         {               
  1157.             if (flagFRAME)
  1158.             { 
  1159.                 libPrintString(TAG_CITE, fpNote);
  1160.                 libPrintString(lesNotes[i], fpNote);
  1161.                 libPrintString(TAGf_CITE, fpNote);
  1162.                 libPrintCharStd('\n', fpNote);
  1163.             }
  1164.             else
  1165.             {
  1166.                 libPrintString(TAG_CITE, fpOut);
  1167.                 libPrintString(lesNotes[i], fpOut);
  1168.                 libPrintString(TAGf_CITE, fpOut);
  1169.                 libPrintCharStd('\n', fpOut);
  1170.             }
  1171.         }
  1172.  
  1173.         if(flagBR_P)
  1174.         {
  1175.             if (flagFRAME)
  1176.                 libPrintString(TAG_P, fpNote);
  1177.             else
  1178.                 libPrintString(TAG_P, fpOut);
  1179.         }
  1180.         else
  1181.         {
  1182.             if (flagFRAME)
  1183.                 libPrintString(TAG_BR, fpNote);
  1184.             else
  1185.                 libPrintString(TAG_BR, fpOut);
  1186.         }
  1187.  
  1188.         lesNotes[i][0] = '\0';
  1189.     }
  1190.  
  1191.     carnot = 0;
  1192.     nbnote = 0;
  1193.     lesNotes[nbnote][0] = '\0';
  1194.     Notes[carnot] = '\0';
  1195. }
  1196.       
  1197. /* 
  1198.  * %%Function: ecPrintItalic.
  1199.  *
  1200.  * Affiche un style italique. 
  1201.  */
  1202. void ecPrintItalic(FILE * sortie)
  1203. {
  1204.     if (styleItalic || !crochet)
  1205.         return ;
  1206.     
  1207.     valCrochetI = crochet;
  1208.     styleItalic = 1;
  1209.     
  1210.     TestLibPrintString(TAG_I, sortie);
  1211. }
  1212.  
  1213. /* 
  1214.  * %%Function: ecPrintItalicF
  1215.  *
  1216.  * Affiche une fin de style italique. 
  1217.  */
  1218. void ecPrintItalicF(FILE * sortie)
  1219. {          
  1220.     if (!styleItalic)
  1221.         return ;
  1222.     
  1223.     if (valCrochetI != crochet)
  1224.         return ;
  1225.         
  1226.     valCrochetI = 0;
  1227.     styleItalic = 0;
  1228.     
  1229.     TestLibPrintString(TAGf_I, sortie); 
  1230. }
  1231.  
  1232.  
  1233. /* 
  1234.  * %%Function: ecPrintBold.
  1235.  *
  1236.  * Affiche un style gras. 
  1237.  */
  1238. void ecPrintBold(FILE * sortie)
  1239. {          
  1240.     if (styleBold || !crochet)
  1241.         return ;
  1242.          
  1243.     valCrochetB = crochet;
  1244.     styleBold = 1;
  1245.     
  1246.     TestLibPrintString(TAG_B, sortie);
  1247. }
  1248.  
  1249. /* 
  1250.  * %%Function: ecPrintBoldF.
  1251.  *
  1252.  * Affiche une fin de style gras. 
  1253.  */
  1254. void ecPrintBoldF(FILE * sortie)
  1255. {         
  1256.     if (!styleBold)
  1257.         return ;
  1258.             
  1259.     if (valCrochetB != crochet)
  1260.         return ;
  1261.         
  1262.     valCrochetB = 0;
  1263.     styleBold = 0;
  1264.     
  1265.     TestLibPrintString(TAGf_B, sortie);
  1266. }
  1267.  
  1268.  
  1269. /* 
  1270.  * %%Function: ecPrintCenter.
  1271.  *
  1272.  * Affiche une centre HTML. 
  1273.  */
  1274. void ecPrintCenter(FILE * sortie)
  1275. {
  1276.     tagCenter = 1;
  1277.     
  1278.     TestLibPrintString(TAG_CENTER, sortie);
  1279.     TestLibPrintString("\n", fpOut);
  1280. }
  1281.